/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "iccreader_srv_proxy.h"
#include <string.h>
#include "ipc_types.h"
#include "message_option.h"
#include "message_parcel.h"
#include "iccreader_hilog.h"
#include "iccreader_errors.h"
#include "iccreader_common.h"
#include "iccreader_def.h"
#include "iccreader_observer_stub.h"

namespace SwanLink {
namespace Finance {

int IccreaderSrvProxy::GetDeviceInfo(int fd, DeviceInfo &devInfo)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if(remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(IccreaderSrvProxy::GetDescriptor())) {
        ICCREADER_HILOGE(ICCREADER_SRV, "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data,Int32,fd,-1);
    
    int ret = remote->SendRequest(static_cast<int>(IIccreaderSrv::ICCREADER_GETDEVICEINFO), data, reply, option);

    if (ret != ERR_OK) {
        ICCREADER_HILOGE(ICCREADER_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_BUFFER_WITH_COPY(reply, DeviceInfo, &devInfo, sizeof(devInfo));
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int IccreaderSrvProxy::IccIOCtrl(int fd, IOType type, int value)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if(remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(IccreaderSrvProxy::GetDescriptor())) {
        ICCREADER_HILOGE(ICCREADER_SRV, "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data,Int32,fd,-1);
    WRITE_PARCEL_WITH_RET(data,Int32,type,-1);
    WRITE_PARCEL_WITH_RET(data,Int32,value,-1);
    
    int ret = remote->SendRequest(static_cast<int>(IIccreaderSrv::ICCREADER_ICCIOCTRL), data, reply, option);

    if (ret != ERR_OK) {
        ICCREADER_HILOGE(ICCREADER_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply,Int32,result,-1);

    return result;
}

int IccreaderSrvProxy::ApduCommand(int fd, IOType type, int len, uint8_t cmd[], uint8_t cmd_out[])
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if(remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(IccreaderSrvProxy::GetDescriptor())) {
        ICCREADER_HILOGE(ICCREADER_SRV, "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data,Int32,fd,-1);
    WRITE_PARCEL_WITH_RET(data,Int32, type, -1);
    WRITE_PARCEL_WITH_RET(data,Int32,len,-1);
    if (len > 0)
        WRITE_BUFFER_WITH_RET(data, String, cmd, len, -1);  
    
    int ret = remote->SendRequest(static_cast<int>(IIccreaderSrv::ICCREADER_APDUCOMMAND), data, reply, option);

    if (ret != ERR_OK) {
        ICCREADER_HILOGE(ICCREADER_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply,Int32,result,-1);

    if (result > 0)
        READ_BUFFER_WITH_COPY(reply,uint8_t,cmd_out,result);
    
    return result;
}

int IccreaderSrvProxy::CardSearch(int fd, int timeout, SearchResult *search)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if(remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(IccreaderSrvProxy::GetDescriptor())) {
        ICCREADER_HILOGE(ICCREADER_SRV, "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data,Int32,fd,-1);
    WRITE_PARCEL_WITH_RET(data,Int32,timeout,-1);

    IIccReaderObserver *remote_object = static_cast<IIccReaderObserver*>(search);
    if (remote_object) {
        if (!data.WriteRemoteObject(remote_object->AsObject())) {
            ICCREADER_HILOGE(ICCREADER_SRV,  "WriteRemoteObject is failed");
            return -1;
        }
    }
    
    int ret = remote->SendRequest(static_cast<int>(IIccreaderSrv::ICCREADER_CARDSEARCH), data, reply, option);

    if (ret != ERR_OK) {
        ICCREADER_HILOGE(ICCREADER_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result,-1);

    return result;
}

int IccreaderSrvProxy::CardStopSearch(int fd)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if(remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(IccreaderSrvProxy::GetDescriptor())) {
        ICCREADER_HILOGE(ICCREADER_SRV, "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data,Int32,fd,-1);
    
    int ret = remote->SendRequest(static_cast<int>(IIccreaderSrv::ICCREADER_CARDSTOPSEARCH), data, reply, option);

    if (ret != ERR_OK) {
        ICCREADER_HILOGE(ICCREADER_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply,Int32,result,-1);

    return result;
}

int IccreaderSrvProxy::RfCardActive(int fd, RfCardInfo &cardInfo)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if(remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(IccreaderSrvProxy::GetDescriptor())) {
        ICCREADER_HILOGE(ICCREADER_SRV, "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data,Int32,fd,-1);
    
    int ret = remote->SendRequest(static_cast<int>(IIccreaderSrv::ICCREADER_RFCARDACTIVE), data, reply, option);

    if (ret != ERR_OK) {
        ICCREADER_HILOGE(ICCREADER_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_BUFFER_WITH_COPY(reply, RfCardInfo, &cardInfo,sizeof(cardInfo));
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int IccreaderSrvProxy::RfCardDormancy(int fd)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if(remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(IccreaderSrvProxy::GetDescriptor())) {
        ICCREADER_HILOGE(ICCREADER_SRV, "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data,Int32,fd,-1);
    
    int ret = remote->SendRequest(static_cast<int>(IIccreaderSrv::ICCREADER_RFCARDDORMANCY), data, reply, option);

    if (ret != ERR_OK) {
        ICCREADER_HILOGE(ICCREADER_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply,Int32,result,-1);

    return result;
}

int IccreaderSrvProxy::ScanData(int fd, const DeviceConfig& config, ResultData &out)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if(remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(IccreaderSrvProxy::GetDescriptor())) {
        ICCREADER_HILOGE(ICCREADER_SRV, "Write descriptor failed");
        return result;
    }

    out.type = config.devType;
    
    WRITE_PARCEL_WITH_RET(data, Int32, fd, -1);
    WRITE_BUFFER_WITH_RET(data, DeviceConfig, &config, sizeof(config), -1);
    
    int ret = remote->SendRequest(static_cast<int>(IIccreaderSrv::ICCREADER_SCANDATA), data, reply, option);

    if (ret != ERR_OK) {
        ICCREADER_HILOGE(ICCREADER_SRV, "SendRequest is failed, ret: %d", ret);
        return result;
    }
    READ_BUFFER_WITH_COPY(reply, ResultData, &out, sizeof(out));
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}


} // namespace Finance
} // namespace SwanLink
